package ar.com.utn.openqsb.lip.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import ar.com.utn.openqsb.lip.core.Constraint.Relation;

public class SimplexModel
{

	private int numVar;

	private Objective objective;

	private List<Constraint> constraints;

	public SimplexModel(final int numVars, final int numConstraints)
	{
		this.numVar = numVars;
		this.constraints = new ArrayList<Constraint>(numConstraints);
		for (int i = 0; i < numConstraints; i++)
		{
			this.constraints.add(new Constraint(numVars));
		}
	}

	public int getNumVars()
	{
		return numVar;
	}

	public int getNumConstraints()
	{
		return constraints.size();
	}

	public void setObjective(final Objective objective)
	{
		this.objective = objective;
	}

	public Objective getObjective()
	{
		return objective;
	}

	public void setConstraint(final int index, final Constraint constraint)
	{
		constraints.set(index, constraint);
	}
	
	public List<Constraint> getConstraints(){
	    return constraints;
	}

	/**
	 * Returns new versions of the constraints which have positive right hand
	 * sides.
	 */
	public List<Constraint> getNormalizedConstraints()
	{
		List<Constraint> normalized = new ArrayList<Constraint>();
		for (Constraint constraint : constraints)
		{
			normalized.add(normalize(constraint));
		}
		return normalized;
	}

	/**
	 * Returns a new equation equivalent to this one with a positive right hand
	 * side.
	 */
	private Constraint normalize(Constraint constraint)
	{
		if (constraint.getRightValue() < 0)
		{
			return new Constraint(constraint.getCoefficients().mapMultiply(-1), constraint.getRelation().opposite(), constraint.getRightValue() * -1);
		}
		return new Constraint(constraint.getCoefficients().copy(), constraint.getRelation(), constraint.getRightValue());
	}

	/**
	 * Returns a map from constraint type to count of the corresponding
	 * constraint type.
	 */
	public Map<Relation, Integer> getConstraintTypeCounts()
	{
		Map<Relation, Integer> counts = new HashMap<Relation, Integer>();
		for (Relation relationship : Relation.values())
		{
			counts.put(relationship, 0);
		}
		for (Constraint constraint : constraints)
		{
			counts.put(constraint.getRelation(), counts.get(constraint.getRelation()) + 1);
		}
		return counts;
	}
}
